#pragma once
#include <iostream>
#include <sys/epoll.h>
#include "mylog.hpp"
#include "common.hpp"
#include "Addr.hpp"
using namespace my_log;
class Epoller
{
public:
    Epoller()
        : _epfd(-1)
    {
        // 创建一个进程epoll模型
        _epfd = epoll_create(128);
        if (_epfd < 0)
        {
            LOG(LogLevel::FATAL) << "epoll_create error...";
            exit(epoll_create_err);
        }
    }
    int Epfd()
    {
        return _epfd;
    }
    // 下边是对epoll进行增删改的操作函数
    void AddEvent(int fd, uint32_t events)
    {
        // 将其设置进入内核
        struct epoll_event ev;
        ev.data.fd = fd;
        ev.events = events;
        int n = epoll_ctl(_epfd, EPOLL_CTL_ADD, fd, &ev);
        if(n<0)
        {
            LOG(LogLevel::ERROR)<<"epoll_ctl error...";
        }
    }
    void DelEvent(int fd)
    {  
        int n=epoll_ctl(_epfd,EPOLL_CTL_DEL,fd,nullptr);
        if(n<0)
        {
            //epoll_ctl失败
            LOG(LogLevel::ERROR)<<"删除fd:"<<fd<<"失败...";
            return;
        }
    }
    void ModEvent(int fd,uint32_t events)
    {
        struct epoll_event ev;
        ev.data.fd=fd;
        ev.events=events;
        int n=epoll_ctl(_epfd,EPOLL_CTL_MOD,fd,&ev);
        if(n<0)
        {
            //epoll_ctl失败
            LOG(LogLevel::ERROR)<<"更改fd:"<<fd<<"关心事件失败...";
            return;
        }
        if(events&EPOLLOUT)
        {
            LOG(LogLevel::DEBUG)<<"更改fd:"<<fd<<"关心事件为EPOLLOUT成功!";
        }
        else if(events&EPOLLIN)
        {
            LOG(LogLevel::DEBUG)<<"更改fd:"<<fd<<"关心事件为EPOLLIN成功!";
        }
    }
    int WaitEvent(struct epoll_event* revs,int maxevents,int timeout)
    {
        std::cout<<"在WaitEvent"<<std::endl;
        int n=epoll_wait(_epfd,revs,maxevents,timeout);
        std::cout<<"在WaitEvent中,n="<<n<<std::endl;
        if(n<0)
        {
            LOG(LogLevel::ERROR)<<"epoll_wait err...";\
            return -1;
        }
        else if(n==0)
        {
            LOG(LogLevel::DEBUG)<<"epoll_wait timeout...";
            return -1;
        }
        else
        {
            return n;
        }
    }
    ~Epoller()
    {
        if (_epfd > 0)
        {
            close(_epfd);
        }
    }

private:
    int _epfd;
};